package org.achievement.system.common.interceptor;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import org.achievement.system.common.annotations.InterfaceAuth;
import org.achievement.system.common.consts.Consts;
import org.achievement.system.common.enums.AuthEnum;
import org.achievement.system.common.exception.ServiceException;
import org.achievement.system.pojo.entity.Role;
import org.achievement.system.pojo.entity.User;
import org.achievement.system.service.RoleService;
import org.achievement.system.service.UserService;
import org.achievement.system.common.utils.SpringContextUtil;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;

/**
 * 登陆检查
 */
public class RequestHandlerInterceptor implements HandlerInterceptor {

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws IOException, ServletException {
        // 排除对登录和注册页面的拦截
        String uri = request.getRequestURI();
        for (String pattern : Consts.EXCLUDE_PATH_PATTERNS) {
            if (uri.endsWith(pattern)) {
                return true;
            }
        }
        //打印日志：
        //检测登录逻辑
        HttpSession session=request.getSession();
        String username = (String) session.getAttribute("username");
        if (username != null){
            try {
                checkUser(username, handler);
            } catch (Exception e) {
                request.setAttribute("msg",e.getMessage());
                response.sendRedirect(request.getContextPath() + "/login");
                // 阻止请求继续处理
                return false;
            }
            //已登录，直接跳转到首页
            if ("/".equals(uri) || "/login".equals(uri)) {
                request.getRequestDispatcher("/index").forward(request, response);
            }
            return true;
        }
        //转发到login页面
        request.getRequestDispatcher("/login").forward(request, response);
        // 阻止请求继续处理
        return false;
    }

    /**
     * 检查用户权限
     */
    private void checkUser(String username, Object handle) {
        if (! (handle instanceof HandlerMethod)) {
            return;
        }
        HandlerMethod handlerMethod = (HandlerMethod) handle;
        UserService userService = SpringContextUtil.getBean(UserService.class);
        RoleService roleService = SpringContextUtil.getBean(RoleService.class);

        User user = userService.getOne(new QueryWrapper<User>().eq("username", username));
        if (user == null) {
            throw new ServiceException("错误！");
        }
        Role role = roleService.getOne(new QueryWrapper<Role>().eq("id", user.getRoleId()));
        if (role == null) {
            throw new ServiceException("没有权限！");
        }
        String roleName = role.getName();
        InterfaceAuth annotation = handlerMethod.getMethod().getAnnotation(InterfaceAuth.class);
        if (annotation != null) {
            AuthEnum[] value = annotation.value();
            // 验证通过
            boolean isPass = false;
            for (AuthEnum authEnum : value) {
                if (authEnum.getRoleName().equals(roleName)) {
                    isPass = true;
                }
            }
            if ( ! isPass) {
                throw new ServiceException("没有权限！");
            }
        }
//        else {
//            throw new ServiceException("此接口没有设置权限！");
//        }
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        System.out.println("\n-------- AuthHandlerInterceptor.postHandle --- ");
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        System.out.println("\n-------- AuthHandlerInterceptor.afterCompletion --- ");
    }
}
